﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using UMLTouch.Core.UI;
using System.Collections.Specialized;
using UMLTouch.Core.ViewModel;

namespace UMLTouch.UI.Controls
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:UMLTouch.UI.Controls"
    ///
    ///
    /// Step 1b) Using this custom control in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:UMLTouch.UI.Controls;assembly=UMLTouch.UI.Controls"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Browse to and select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your control in the XAML file.
    ///
    ///     <MyNamespace:DiagramCanvas/>
    ///
    /// </summary>
    public class DiagramCanvas : InkCanvas
    {



        public Boolean SelectionMode
        {
            get { return (Boolean)GetValue(SelectionModeProperty); }
            set { SetValue(SelectionModeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectionMode.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectionModeProperty =
            DependencyProperty.Register("SelectionMode",
            typeof(Boolean),
            typeof(DiagramCanvas),
            new FrameworkPropertyMetadata(false,
            new PropertyChangedCallback(SelectionModeChanged)));

        protected static void SelectionModeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            var instance = sender as DiagramCanvas;
            if ((Boolean)args.NewValue)
            {
                instance.EditingMode = InkCanvasEditingMode.Select;
            }
            else
            {
                instance.EditingMode = InkCanvasEditingMode.Ink;
            }

        }
        //Just a simple INotifyCollectionChanged collection
        public DiagramItemsViewModelCollection Source
        {
            get { return (DiagramItemsViewModelCollection)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

       
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source",
            typeof(DiagramItemsViewModelCollection),
            typeof(DiagramCanvas),
            new FrameworkPropertyMetadata(new DiagramItemsViewModelCollection(),
            new PropertyChangedCallback(SourceChanged)));

        //called when a new value is set (through binding for example)
        protected static void SourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {

            var instance = sender as DiagramCanvas;
           
            DiagramItemsViewModelCollection newCollection = args.NewValue as DiagramItemsViewModelCollection;
            DiagramItemsViewModelCollection oldCollection = args.OldValue as DiagramItemsViewModelCollection;

            if (oldCollection != null)
            {
                oldCollection.CollectionChanged -= new NotifyCollectionChangedEventHandler(instance.collection_CollectionChanged);
            }

            instance.Children.Clear();

            if (newCollection != null)
            {
                foreach (DiagramItemViewModel item in newCollection)
                {
                    AddControl(item, instance);
                }

                newCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(instance.collection_CollectionChanged);

            }

        }


        //append when an Item in the collection is changed
        protected void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {


            foreach (DiagramItemViewModel item in e.NewItems)
            {
                AddControl(item); 
            }

            //List<UIElement> elementsToRemove = new List<UIElement>();
            //foreach (DiagramItemViewModel item in e.OldItems)
            //{
               
            //    foreach (UIElement element in Children)
            //    {
            //        if (element is DiagramItem
            //         && (element as DiagramItem).DataContext == item)
            //        {
            //            elementsToRemove.Add(element);
            //        }

            //    }
            //}

            //foreach (var item in elementsToRemove)
            //{
            //    Children.Remove(item);
            //}
        }


        protected static void AddControl(DiagramItemViewModel diagramItem, InkCanvas parentControl)
        {
            Control ret = new DiagramItem();
            ret.DataContext = diagramItem;
            parentControl.Children.Add(ret);

            Binding XBinding = new Binding("X");
            XBinding.Source = diagramItem;
            XBinding.Mode = BindingMode.TwoWay;

            Binding YBinding = new Binding("Y");
            YBinding.Source = diagramItem;
            YBinding.Mode = BindingMode.TwoWay;

            ret.SetBinding(InkCanvas.LeftProperty, XBinding);
            ret.SetBinding(InkCanvas.TopProperty, YBinding);

            

        }

        protected void AddControl(DiagramItemViewModel diagramItem)
        {
            AddControl(diagramItem, this);
        }


        static DiagramCanvas()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DiagramCanvas), new FrameworkPropertyMetadata(typeof(DiagramCanvas)));
        }

        public DiagramCanvas()
            : base()
        {
           // Source = new DiagramItemsCollection();
            
        }

        



    }
}
